package repository

import (
	"context"
	"net/http"
	"server/components/errors"
	"server/components/models/ent"
	"server/components/models/ent/forecast"
	"time"
)

func GetForecastByID(ctx context.Context, id int64) (*Forecast, errors.RequestError) {
	f, err := EntClient().Forecast.Query().Where(forecast.ID(id)).WithRegion().Only(ctx)
	if ent.IsNotFound(err) {
		return nil, errors.New("Прогноз с таким id не найден", http.StatusNotFound)
	}
	return &Forecast{
		ID:                  f.ID,
		RegionId:            f.Edges.Region.ID,
		Temperature:         f.Temperature,
		WeatherCondition:    f.WeatherCondition.String(),
		DateTime:            f.DateTime.Format(time.RFC3339),
		PrecipitationAmount: f.PrecipitationAmount,
		WindSpeed:           f.WindSpeed,
	}, nil
}

func UpdateForecastByID(ctx context.Context, id int64, req ForecastUpdateRequest) (*Forecast, errors.RequestError) {
	_, err := EntClient().Forecast.Query().Where(forecast.ID(id)).WithRegion().Only(ctx)
	if ent.IsNotFound(err) {
		return nil, errors.New("Прогноз с таким id не найден", http.StatusNotFound)
	}
	update := EntClient().Forecast.UpdateOneID(id)
	if req.DateTime != nil {
		dt, err := ParseTime(*req.DateTime)
		if err != nil {
			return nil, errors.New("Некорректный формат даты", http.StatusBadRequest)
		}
		update = update.SetDateTime(dt)
	}
	if req.Temperature != nil {
		update = update.SetTemperature(*req.Temperature)
	}
	if req.WeatherCondition != nil {
		update = update.SetWeatherCondition(forecast.WeatherCondition(*req.WeatherCondition))
	}
	if req.PrecipitationAmount != nil {
		update = update.SetPrecipitationAmount(*req.PrecipitationAmount)
	}
	if req.WindSpeed != nil {
		update = update.SetWindSpeed(*req.WindSpeed)
	}
	if _, err := update.Save(ctx); err != nil {
		return nil, errors.New("Некорректные данные", http.StatusBadRequest)
	}
	return GetForecastByID(ctx, id)
}

func AddForecast(ctx context.Context, req ForecastAddRequest) (*Forecast, errors.RequestError) {
	if _, err := EntClient().Region.Get(ctx, req.RegionId); ent.IsNotFound(err) {
		return nil, errors.New("Регион не найден", http.StatusNotFound)
	}
	create := EntClient().Forecast.Create()
	dt, err := ParseTime(req.DateTime)
	if err != nil {
		return nil, errors.New("Некорректный формат даты", http.StatusBadRequest)
	}
	create = create.
		SetDateTime(dt).
		SetRegionID(req.RegionId).
		SetTemperature(req.Temperature).
		SetWeatherCondition(forecast.WeatherCondition(req.WeatherCondition))
	if req.WindSpeed != nil {
		create = create.SetWindSpeed(*req.WindSpeed)
	}
	if req.PrecipitationAmount != nil {
		create = create.SetPrecipitationAmount(*req.PrecipitationAmount)
	}
	f, err := create.Save(ctx)
	if err != nil {
		return nil, errors.New("Некорректные данные", http.StatusBadRequest)
	}
	return GetForecastByID(ctx, f.ID)
}

func DeleteForecastByID(ctx context.Context, id int64) errors.RequestError {
	err := EntClient().Forecast.DeleteOneID(id).Exec(ctx)
	if ent.IsNotFound(err) {
		return errors.New("Прогноз с таким id не найден", http.StatusNotFound)
	}
	return nil
}
